package com.heima.juc.unlock;

import lombok.extern.slf4j.Slf4j;

import java.time.Duration;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * @author : leimingchao
 * @date Date : 2022年02月12日 15:30
 */
@Slf4j(topic = "c.TestAccount3")
public class TestAccount3 {

    public static void main(String[] args) {

        Account3 account3 = new AccountCas3(10000);
        Account3.demo(account3);
    }
}

class AccountCas3 implements Account3 {

    private AtomicInteger balance;

    public AccountCas3(int balance) {
        this.balance = new AtomicInteger(balance);
    }

    @Override
    public Integer getBalance() {
        return balance.get();
    }

    @Override
    public void withdraw(Integer amount) {
        // while (true) {
        //     //获取余额最新值
        //     int prev = balance.get();
        //     //要修改的余额
        //     int next = prev - amount;
        //
        //     //真正修改
        //     if (balance.compareAndSet(prev, next)) {
        //         break;
        //     }
        // }
        balance.getAndAdd( -1 * amount);
    }
}

interface Account3 {

    /**
     * 获得余额
     */
    Integer getBalance();

    void withdraw(Integer amount);

    /**
     * 方法内会启动1000个线程，每个线程做 - 10 元的操作
     * 如果初始余额为10000 那么正确的结果应当是 0
     * @param account
     */
    static void demo(Account3 account) {

        List<Thread> ts = new ArrayList<>();
        for (int i = 0; i < 1000; i++) {
            ts.add(new Thread(() -> {
                account.withdraw(10);
            }));

        }

        LocalDateTime start = LocalDateTime.now();

        ts.forEach(Thread::start);

        ts.forEach(t -> {
            try {
                t.join();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        });

        LocalDateTime end = LocalDateTime.now();

        System.out.println(account.getBalance() + " cost: " + Duration.between(start, end).toMillis() + " ms");
    }
}
